package utils

import org.eclipse.jgit.api.Git
import org.eclipse.jgit.internal.storage.file.FileRepository
import org.eclipse.jgit.lib.Constants
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider

final class GitHelper {

    private static final remoteUri = "http://192.168.0.9:3000/marsdonne/API-Gateway-Config.git"
    private static
    final credentialsProvider = new UsernamePasswordCredentialsProvider("marsdonne", "lovelele99")

    static Serializable cover(String filename, String content) {
        def uniqueTestGitDir = File.createTempFile("jgit_local_repo_cover_$filename", null)
        if (!(uniqueTestGitDir.delete() && uniqueTestGitDir.mkdir()))
            throw new IOException("Cannot create " + uniqueTestGitDir)

        def localGitDir = new File(uniqueTestGitDir.path + "/$Constants.DOT_GIT")

        Git.cloneRepository()
                .setURI(remoteUri)
                .setCredentialsProvider(credentialsProvider)
                .setDirectory(uniqueTestGitDir)
                .call().close()

        def localRepo = new FileRepository(localGitDir)
        def localGit = new Git(localRepo)

        def targetFile = new File(localRepo.getWorkTree(), filename)
        targetFile.text = content
        localGit.add().addFilepattern(filename).call()

        def commit = localGit.commit().setMessage("commit to push").call()
        def pushResults = localGit.push().setRemote(remoteUri).setCredentialsProvider(credentialsProvider).call()

        localRepo.close()
        recursiveDelete(uniqueTestGitDir, false, true)

        [commitId: commit.id, remoteUpdates: pushResults.collect { it.remoteUpdates }]
    }

    private static boolean recursiveDelete(final File dir, boolean silent, boolean failOnError) {
        assert !(silent && failOnError)
        if (!dir.exists())
            return silent
        final File[] ls = dir.listFiles()
        if (ls != null)
            for (int k = 0; k < ls.length; k++) {
                final File e = ls[k]
                if (e.isDirectory())
                    silent = recursiveDelete(e, silent, failOnError)
                else if (!e.delete()) {
                    if (!silent)
                        reportDeleteFailure(failOnError, e)
                    silent = !failOnError
                }
            }
        if (!dir.delete()) {
            if (!silent)
                reportDeleteFailure(failOnError, dir)
            silent = !failOnError
        }
        return silent
    }

    private static void reportDeleteFailure(boolean failOnError, File e) {
        String severity = failOnError ? "ERROR" : "WARNING"
        String msg = severity + ": Failed to delete " + e
        if (failOnError)
            throw new RuntimeException(msg)
        else
            System.err.println(msg)
    }
}
